﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.AccessControl;
using Microsoft.Win32;

namespace MigrationTool
{
    public static class RegistryEdit
    {
        private const string REG_KEY_PROFILE = @"Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles";
        private const string REG_KEY_SETUP = @"Software\Microsoft\Office\14.0\Outlook\Setup";
        private const string REG_KEY_FIRSTRUN = "First-Run";
        private const string REG_KEY_IMPORTPRF = "ImportPRF";

        /// <summary>
        /// 指定されたレジストリキーのサブキーの名前を取得する
        /// </summary>
        /// <param name="parentKeyName">親となるレジストリキー</param>
        /// <returns>指定されたレジストリキーのサブキーの名前</returns>
        public static string[] GetSubKeyNames(string parentKeyName)
        {
            string[] subKeys = null;

            lock (typeof(RegistryEdit))
            {
                using (RegistryKey rootKey = Registry.CurrentUser)
                {
                    using (RegistryKey parentKey = rootKey.OpenSubKey(parentKeyName,
                                                RegistryKeyPermissionCheck.ReadSubTree,
                                                RegistryRights.ReadKey))
                    {
                       subKeys = parentKey.GetSubKeyNames();
                    }
                }
            }

            return subKeys;
        }

        /// <summary>
        /// 指定されたレジストリの値を取得する
        /// </summary>
        /// <param name="parentKeyName">親となるレジストリキー</param>
        /// <param name="targetName">レジストリの名前</param>
        /// <returns>指定されたレジストリの値</returns>
        public static object ReadRegistryValue(string parentKeyName, string targetName)
        {
            object value = string.Empty;

            lock (typeof(RegistryEdit))
            {
                using (RegistryKey rootKey = Registry.CurrentUser)
                {
                    using (RegistryKey targetKey = rootKey.OpenSubKey(parentKeyName,
                                                RegistryKeyPermissionCheck.ReadSubTree,
                                                RegistryRights.ReadKey))
                    {
                        value = targetKey.GetValue(targetName);
                    }
                }
            }

            return value;
        }

        /// <summary>
        /// 指定されたレジストリに値をセットする
        /// </summary>
        /// <param name="parentKeyName">親となるレジストリキー</param>
        /// <param name="targetName">対象となるレジストリの名前</param>
        /// <param name="registryValue">セットする値</param>
        /// <param name="dataType">レジストリのデータ型</param>
        public static void SetRegistryValue(string parentKeyName, string targetName, object registryValue, RegistryDataType dataType)
        {
            string value = string.Empty;

            lock (typeof(RegistryEdit))
            {
                using (RegistryKey rootKey = Registry.CurrentUser)
                {
                    using (RegistryKey targetKey = rootKey.OpenSubKey(parentKeyName,
                                                RegistryKeyPermissionCheck.ReadWriteSubTree,
                                                RegistryRights.SetValue))
                    {
                        switch (dataType)
                        {
                            case RegistryDataType.String:
                                targetKey.SetValue(targetName, registryValue, RegistryValueKind.String);
                                break;
                            case RegistryDataType.MultiString:
                                targetKey.SetValue(targetName, registryValue, RegistryValueKind.MultiString);
                                break;
                            case RegistryDataType.ExpandString:
                                targetKey.SetValue(targetName, registryValue, RegistryValueKind.ExpandString);
                                break;
                            case RegistryDataType.Binary:
                                targetKey.SetValue(targetName, registryValue, RegistryValueKind.Binary);
                                break;
                            case RegistryDataType.QWord:
                                targetKey.SetValue(targetName, registryValue, RegistryValueKind.QWord);
                                break;
                            case RegistryDataType.DWord:
                                targetKey.SetValue(targetName, registryValue, RegistryValueKind.DWord);
                                break;
                            default:
                                targetKey.SetValue(targetName, registryValue);
                                break;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 指定されたレジストリキーをサブキーごと削除する
        /// </summary>
        /// <param name="parentKeyName">親となるレジストリキー</param>
        /// <param name="targetSubKeyName">対象のレジストリキー</param>
        public static void DeleteRegistryKey(string parentKeyName, string targetSubKeyName)
        {
            string value = string.Empty;
            
            lock (typeof(RegistryEdit))
            {
                using (RegistryKey rootKey = Registry.CurrentUser)
                {
                    using (RegistryKey parentKey = rootKey.OpenSubKey(parentKeyName,
                                                RegistryKeyPermissionCheck.ReadWriteSubTree,
                                                RegistryRights.Delete))
                    {

                        parentKey.DeleteSubKeyTree(targetSubKeyName, false);
                    }
                }
            }
        }

        /// <summary>
        /// レジストリを編集
        /// </summary>
        /// <param name="EntryFilePath"></param>
        public static void EditRegistry(string EntryFilePath)
        {
            EraseRegistryFirstRun();
            EntryRestryImportPRF(EntryFilePath);
        }

        /// <summary>
        /// First-Runを削除
        /// </summary>
        public static void EraseRegistryFirstRun()
        {
            Microsoft.Win32.RegistryKey regEraseKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(REG_KEY_SETUP, true);
            try
            {
                regEraseKey.DeleteValue(REG_KEY_FIRSTRUN);
            }
            catch
            {
            }
            regEraseKey.Close();
        }

        /// <summary>
        /// レジストリからプロファイルを削除する
        /// </summary>
        /// <param name="profileName"></param>
        public static void DeleteOutlookProfile(string profileName)
        {
            try
            {
                //レジストリからプロファイルをサブキーごと削除する
                RegistryEdit.DeleteRegistryKey(REG_KEY_PROFILE, profileName);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// ImportPRFを追加
        /// </summary>
        /// <param name="EntryFilePath">インポート対象のPRFファイルパス</param>
        public static void EntryRestryImportPRF(string EntryFilePath)
        {
            Microsoft.Win32.RegistryKey regEntryKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(REG_KEY_SETUP);
            regEntryKey.SetValue(REG_KEY_IMPORTPRF, EntryFilePath);
            regEntryKey.Close();
        }

    }
}
